home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
edit
/
pt20pc.zip
/
LINES.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-04
|
9KB
|
351 lines
#include "pt.h"
int pascal
/* XTAG:movenl */
movenl(addr, len, buffer, makeLowerCase)
unsigned char far *addr;
unsigned char *buffer;
register int len;
int makeLowerCase;
{
register unsigned char ch;
while( len-- > 0 ) {
ch = *addr++;
if( makeLowerCase && 'A' <= ch && ch <= 'Z' )
ch += 'a' - 'A';
*buffer++ = ch;
if( ch == '\n' )
return len;
}
return -1;
}
long pascal
/* XTAG:readLine */
readLine(fileId, cp, buffer, makeLowerCase)
int fileId, makeLowerCase;
long cp;
unsigned char *buffer;
{
extern struct openFile *files;
extern unsigned char msgBuffer[];
extern int debug;
static int iBuffer, iCount;
int len, left, incr, eof;
long loBuf, hiBuf;
register unsigned char ch;
unsigned char far *addrBuf;
unsigned char far *firstByte;
unsigned char far *dummy;
unsigned char **fp;
register struct openFile *ff;
/* see if the file is there */
if( fileId == -1 ) {
buffer[0] = 0;
return 0L;
}
/* for efficiency, keep some addresses */
ff = &files[fileId];
if( ff->origHandle == -1 ) {
buffer[0] = 0;
return 0L;
}
/* see if the logical byte number is invalid */
if( cp < 0 ) {
sprintf(msgBuffer,
"readLine: character pointer is negative (%ld)", cp);
msg(msgBuffer, 3);
return 0L;
} else if( cp >= ff->fileSize) {
buffer[0] = 0;
return ff->fileSize;
}
/* iBuffer is the next free byte in the buffer */
iBuffer = 0;
iCount = 0;
/* this loop gets the characters one per loop iteration */
/* these three variables are for quick access to structure parts */
loBuf = ff->loLogBuffer;
hiBuf = ff->hiLogBuffer;
/* addrBuf is set to avoid doing the long subtraction in the loop */
fp = (unsigned char **)&addrBuf;
*fp = ff->logBufOffset + (unsigned int)(cp - loBuf);
*++fp = ff->logBufSegment;
while( iBuffer < (MSGBUFFERSIZE - 1) ) {
/* check for optimized special cases */
if( loBuf <= cp && cp <= hiBuf ) {
/* find out how many bytes left in the buffer */
len = (int)(hiBuf - cp) + 1;
if( (len + iBuffer) > MSGBUFFERSIZE )
len = MSGBUFFERSIZE - iBuffer - 1;
/* do a fast scan for a newline in the buffer */
left = movenl(addrBuf, len, &buffer[iBuffer], makeLowerCase);
if( left < 0 ) { /* no newline was moved into buffer */
cp += len; /* move past buffer */
addrBuf += len;
iBuffer += len; /* move moved 'len' chars */
continue; /* else will hit next (cp>hiBuf) */
} else { /* found nl */
incr = len - left;
cp += incr; /* move past it */
break;
}
} else {
eof = getSpan(fileId, cp, &firstByte, &dummy, 0);
if( eof ) {
buffer[iBuffer++] = 0;
break;
}
ch = *firstByte;
/* the getSpan will have changed these */
loBuf = ff->loLogBuffer;
hiBuf = ff->hiLogBuffer;
/* +1 since we just read ch */
fp = (unsigned char **)&addrBuf;
*fp = ff->logBufOffset + (int)(cp + 1 - loBuf);
*++fp = ff->logBufSegment;
}
++cp;
if( makeLowerCase && 'A' <= ch && ch <= 'Z' )
ch += 'a' - 'A';
buffer[iBuffer++] = ch;
if( ch == '\n' )
break;
}
/* buffer[iBuffer] = '\0'; */
return cp;
}
int pascal
/* XTAG:next1nl */
next1nl(addr, len)
unsigned char far *addr;
register int len;
{
while( len-- > 0 )
if( *addr++ == '\n' )
return len;
return -1;
}
long pascal
/* XTAG:nextLine */
nextLine(fileId, cp, n)
int fileId, *n;
long cp;
{
extern struct openFile *files;
extern unsigned char msgBuffer[];
extern int debug;
long loBuf, hiBuf, oldcp;
register unsigned char ch;
unsigned char far *addrBuf;
unsigned char far *firstByte;
unsigned char far *dummy;
struct longPointer *fp;
register struct openFile *ff;
int nLines, len, left, incr, eof;
/* see if the file is there */
if( fileId == -1 )
return cp;
/* for efficiency, keep some addresses */
ff = &files[fileId];
if( ff->origHandle == -1 ) {
*n = 0;
return 0L;
}
/* see if the logical byte number is invalid */
if( cp < 0 ) {
sprintf(msgBuffer,
"nextLine: invalid character pointer = %ld fileId=%d *n=%d",
cp, fileId, *n);
msg(msgBuffer, 3);
*n = 0;
return 0L;
} else if( cp >= ff->fileSize ) {
*n = 0;
return ff->fileSize;
}
/* this loop get the characters one per loop iteration */
/* these three variables are for speedy access to structure parts */
loBuf = ff->loLogBuffer;
hiBuf = ff->hiLogBuffer;
/* addrBuf is set to avoid doing the long subtraction in the loop */
fp = (struct longPointer *)&addrBuf;
fp->offset = ff->logBufOffset + (int)(cp - loBuf);
fp->segment = ff->logBufSegment;
nLines = 0;
while( nLines < *n ) {
oldcp = cp;
ch = 0;
while( ch != '\n' ) {
/* check for optimized special cases */
if( loBuf <= cp && cp <= hiBuf ) {
/* find out how many bytes left in the buffer */
len = (int)(hiBuf - cp) + 1;
/* do a fast scan for a newline in the buffer */
left = next1nl(addrBuf, len);
if( left < 0 ) { /* no newline in buffer */
cp += len; /* move past buffer */
ch = 0; /* any non-nl char will do */
} else { /* found nl */
incr = len - left;
cp += incr; /* move past it */
addrBuf += incr; /* adjust this too */
break;
}
} else {
eof = getSpan(fileId, cp++, &firstByte, &dummy, 0);
/* increment cp since we already have 'ch' */
if( eof ) { /* end of file */
if( oldcp < --cp ) /* no CRLF at EOF */
++nLines;
goto ret;
}
ch = *firstByte;
/* the getSpan will have changed these */
loBuf = ff->loLogBuffer;
hiBuf = ff->hiLogBuffer;
fp = (struct longPointer *)&addrBuf;
fp->offset = ff->logBufOffset + (int)(cp - loBuf);
fp->segment = ff->logBufSegment;
}
}
++nLines;
}
ret:
*n = nLines;
return cp;
}
int pascal
/* XTAG:prev1nl */
prev1nl(addr, len)
unsigned char far *addr;
register int len;
{
while( len-- > 0 )
if( *addr-- == '\n' )
return len;
return -1;
}
long pascal
/* XTAG:prevLine */
prevLine(fileId, cp, n)
int fileId, *n;
long cp;
{
extern unsigned char msgBuffer[];
extern struct openFile *files;
extern int debug;
long loBuf, hiBuf, oldcp;
register unsigned char ch;
unsigned char far *addrBuf;
struct longPointer *fp;
register struct openFile *ff;
int nLines, len, left, decr;
/* see if the file is there */
if( fileId == -1 )
return cp;
/* for efficiency, keep some addresses */
ff = &files[fileId];
if( ff->origHandle == -1 ) {
*n = 0;
return 0L;
}
/* see if the logical byte number is invalid */
if( cp < 0 ) {
sprintf(msgBuffer,
"prevLine: invalid character pointer = %ld fileId=%d *n=%d",
cp, fileId, *n);
msg(msgBuffer, 3);
*n = 0;
return 0L;
}
/* move past the '\n' unless the search is for the beginning of the line */
if( *n >= 0 )
cp -= 2;
else { /* just find the beginning of this line */
/* this works even when you are already at the beginning */
*n = 1;
/* do this so it also works sitting on the '\n' */
if( readChar(fileId, cp) == '\n' )
--cp;
}
/* this loop get the characters one per loop iteration */
/* these three variables are for speedy access to structure parts */
loBuf = ff->loLogBuffer;
hiBuf = ff->hiLogBuffer;
/* addrBuf is set to avoid doing the long subtraction in the loop */
fp = (struct longPointer *)&addrBuf;
fp->offset = ff->logBufOffset + (int)(cp - loBuf);
fp->segment = ff->logBufSegment;
nLines = 0;
while( nLines < *n ) {
oldcp = cp;
ch = 0;
while( ch != '\n' ) {
/* check for optimized special cases */
if( loBuf <= cp && cp <= hiBuf ) {
/* find out how many bytes left in the buffer */
len = (int)(cp - loBuf) + 1;
/* do a fast scan for a newline in the buffer */
left = prev1nl(addrBuf, len);
if( left < 0 ) { /* no newline in buffer */
cp -= len; /* move past buffer */
ch = 0; /* any non-nl char will do */
} else { /* found nl */
decr = len - left;
cp -= decr; /* move past it */
addrBuf -= decr; /* adjust this too */
break;
}
} else {
ch = readChar(fileId, cp--);
/* decrement cp since we already have 'ch' */
if( ch == 0 && cp < 0 ) { /* beginning of fil